package com.zmn.oms.business.impl.mediadetection;

import com.google.common.collect.Maps;
import com.zmn.base.common.data.common.dro.tags.TagsDRO;
import com.zmn.base.plat.engine.common.constant.DubboConsts;
import com.zmn.base.product.common.dto.categ.CategServDRO;
import com.zmn.base.product.dubbo.interfaces.categ.serv.CategServListRemoteService;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductBusinessLineForeignListRemoteService;
import com.zmn.biz.mds.common.constant.AgentType;
import com.zmn.biz.mds.common.constant.CallTypeConstant;
import com.zmn.biz.mds.common.dio.VoiceDetectionDIO;
import com.zmn.biz.mds.common.enums.AppEnum;
import com.zmn.biz.mds.common.enums.MediaSceneEnum;
import com.zmn.biz.mds.dubbo.interfaces.detection.MediaDetectionRemoteService;
import com.zmn.ccb.common.consts.CCBCallConst;
import com.zmn.common.dto2.Option;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.mediadetection.CallSyncDetectionBService;
import com.zmn.oms.common.constant.MessageQueueTagConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.model.bo.mediadetection.DetectionBO;
import com.zmn.oms.model.entity.mediadetection.MediaDetectionResult;
import com.zmn.oms.model.entity.redistribute.OrderWorkRedistributeApply;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.mediadetection.MediaDetectionResultService;
import com.zmn.oms.services.interfaces.redistribute.OrderWorkRedistributeApplyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 类描述：呼叫数据整合推送质检
 *
 * @author ligang
 * @date 2022/08/08 16:45
 */
@Slf4j
@Service
public class CallSyncDetectionServiceImpl implements CallSyncDetectionBService {

    @Resource
    private OrderWorkService orderWorkService;
    @Resource
    private OrderWorkRedistributeApplyService orderWorkRedistributeApplyService;
    @Resource
    private MediaDetectionResultService mediaDetectionResultService;
    @Resource
    private BaseCodeService baseCodeService;

    @Value("${spring.mq.topic.oms}")
    private String OMS_MQ_TOPIC;

    @DubboReference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private MediaDetectionRemoteService mediaDetectionRemoteService;
    @DubboReference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private CategServListRemoteService categServListRemoteService;
    @DubboReference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private ProductBusinessLineForeignListRemoteService productBusinessLineForeignListRemoteService;

    @Override
    public void syncDetection(DetectionBO detectionBO) {
        if (!this.verify(detectionBO)) {
            return;
        }
        // 组装参数
        Map<String, Object> dataMap = this.getDictData(detectionBO);
        if(CollectionUtil.isNullOrEmpty(dataMap)){
            return;
        }
        Integer cityId = Integer.valueOf(String.valueOf(dataMap.get("cityId")));
        if (!this.isAllowCity(cityId)) {
            return;
        }

        VoiceDetectionDIO detectionDIO = new VoiceDetectionDIO();
        detectionDIO.setBizRecordId(detectionBO.getRecordId().toString());
        detectionDIO.setHangUp(detectionBO.getByeWayCode());
        detectionDIO.setCallType(CallTypeConstant.MANUAL_CALL);
        detectionDIO.setDuration(detectionBO.getEndTime().getTime() - detectionBO.getBridgeTime().getTime());
        detectionDIO.setRecordTime(DateUtil.dateFormatToString(detectionBO.getStartTime(), DateUtil.FORMAT_DEFAULT));
        detectionDIO.setAgentId(detectionBO.getAgentId());
        detectionDIO.setAgentType(AgentType.REAL_AGENT);
        detectionDIO.setAgentName(detectionBO.getAgentName());
        detectionDIO.setDictData(dataMap);
        detectionDIO.setNotifyTopic(OMS_MQ_TOPIC);
        detectionDIO.setNotifyTag(MessageQueueTagConsts.ZMN_TAG_MEDIA_DETECTION_RESULT_NOTICE);
        detectionDIO.setAppBizNo(detectionBO.getZmnBizId());
        detectionDIO.setRecordUrl(detectionBO.getRecordFileUrl());
        detectionDIO.setMediaScene(MediaSceneEnum.SCENE_MANUAL_OUT_CALL.getMediaSceneId());
        detectionDIO.setMediaDetectScene(9581);
        detectionDIO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        detectionDIO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        detectionDIO.setOperator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
        detectionDIO.setAppId(AppEnum.APP_OMS.getAppId());
        detectionDIO.setAppName(AppEnum.APP_OMS.getAppName());

        log.info("CallSyncDetectionServiceImpl#syncDetection#asyncVoiceDetection 入参：{}", detectionDIO);
        ResponseDTO responseDTO = mediaDetectionRemoteService.asyncVoiceDetection(detectionDIO);
        if (!responseDTO.isSuccess()) {
            log.error("CallSyncDetectionServiceImpl#syncDetection#asyncVoiceDetection 失败：{}", responseDTO);
        }
        this.saveResult(detectionBO);
    }

    /**
     * 只保存映射信息 质检结果待监听质检mq消息更新
     *
     * @param detectionBO
     */
    private void saveResult(DetectionBO detectionBO) {
        if (Objects.isNull(detectionBO.getOrderId())) {
            return;
        }
        MediaDetectionResult mediaDetectionResult = new MediaDetectionResult();
        mediaDetectionResult.setOrderId(detectionBO.getOrderId());
        mediaDetectionResult.setBizRecordId(detectionBO.getRecordId());
        mediaDetectionResult.setBizId(Long.valueOf(detectionBO.getZmnBizId()));
        mediaDetectionResult.setDetectResult(GlobalConsts.NONE);
        mediaDetectionResult.setCreater("系统");
        mediaDetectionResult.setUpdater("系统");
        mediaDetectionResultService.addResult(mediaDetectionResult);
    }

    /**
     * 校验
     *
     * @param detectionBO
     */
    private boolean verify(DetectionBO detectionBO) {
        if (Objects.isNull(detectionBO.getOutBusinessTypeCode())) {
            return false;
        }
        if (Objects.isNull(detectionBO.getZmnBizId())) {
            return false;
        }
        if (Objects.isNull(detectionBO.getBridgeTime())) {
            return false;
        }
        if (Objects.isNull(detectionBO.getEndTime())) {
            return false;
        }
        if (Objects.isNull(detectionBO.getByeWayCode())) {
            return false;
        }
        if (StringUtil.isBlank(detectionBO.getRecordFileUrl())) {
            return false;
        }
        return true;
    }

    /**
     * 获取随录字段
     *
     * @return
     */
    private Map<String, Object> getDictData(DetectionBO detectionBO) {
        Map<String, Object> data = Maps.newHashMap();
        switch (detectionBO.getOutBusinessTypeCode()) {
            case CCBCallConst.OUT_BIZ_TYPE_ORDER_DETAIL:
                return getOrdereData(detectionBO);
            case CCBCallConst.OUT_BIZ_TYPE_REASSIGNMENT_REASON:
                return getRedistributeData(detectionBO);
        }
        return data;
    }

    /**
     * 改派随路数据
     *
     * @param detectionBO
     * @return
     */
    private Map<String, Object> getRedistributeData(DetectionBO detectionBO) {
        Long id = Long.valueOf(detectionBO.getZmnBizId());
        OrderWorkRedistributeApply orderWorkRedistributeApply = orderWorkRedistributeApplyService.selectByPrimaryKey(id);
        if (Objects.isNull(orderWorkRedistributeApply)) {
            return Maps.newHashMap();
        }
        Map<String, Object> workOrderData = this.getWorkOrderData(orderWorkRedistributeApply.getOrderId(), orderWorkRedistributeApply.getWorkId());
        detectionBO.setOrderId(orderWorkRedistributeApply.getOrderId());
        workOrderData.put("changeReason", orderWorkRedistributeApply.getReason());
        return workOrderData;
    }

    /**
     * 订单随路数据
     *
     * @param detectionBO
     * @return
     */
    private Map<String, Object> getOrdereData(DetectionBO detectionBO) {
        Long orderId = Long.valueOf(detectionBO.getZmnBizId());
        detectionBO.setOrderId(orderId);
        return this.getWorkOrderData(orderId, orderId);
    }

    /**
     * 订单随路数据
     *
     * @param orderId
     * @param workId
     */
    private Map<String, Object> getWorkOrderData(Long orderId, Long workId) {
        Map<String, Object> data = Maps.newHashMap();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        // 上门状态
        data.put("visitStatus", orderWork.getStatus() >= OrderStatusConsts.ORDER_STATUS_VISIT ? GlobalConsts.YES : GlobalConsts.NO);
        // 订单状态
        data.put("orderStatus", OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        // 产品组
        data.put("productGroup", orderWork.getServProductGroupName());
        // 业务类型
        data.put("bizType", orderWork.getBizType());
        // 拉修待件
        data.put("repairWait", orderWork.getWaitPart());
        // 工单类型
        data.put("workOrderType", orderWork.getType());
        // 工单结果
        data.put("workOrderResult", orderWork.getResultStatus());
        // 测试单
        data.put("isTestOrder", orderWork.getTest());
        // 工程师有无联系
        data.put("isEngineerContact", Objects.nonNull(orderWork.getContactTime()) ? GlobalConsts.YES : GlobalConsts.NO);
        // 质检标签
        data.put("inspectLabel", 5);
        // 业务线
        data.put("bizLine", this.getBizLineName(orderWork.getBizLine()));
        // 服务分类
        data.put("serviceType", this.getServCategName(orderWork.getServCategId()));
        // 城市id
        data.put("cityId", orderWork.getCityId());
        return data;
    }

    /**
     * 获取业务线名称
     *
     * @param bizLineId
     * @return
     */
    private String getBizLineName(Integer bizLineId) {
        try {
            log.info("#CallSyncDetectionServiceImpl#getBizLineName#getOptionNameById 入参：{}", bizLineId);
            ResponseDTO<Option<Integer>> optionResponseDTO = productBusinessLineForeignListRemoteService.getOptionNameById(bizLineId);
            log.info("#CallSyncDetectionServiceImpl#getBizLineName#getOptionNameById 出参：{}", optionResponseDTO);
            if (optionResponseDTO.isSuccess() && Objects.nonNull(optionResponseDTO.getData())) {
                return optionResponseDTO.getData().getLabel();
            }
        } catch (Exception e) {
            log.info("#CallSyncDetectionServiceImpl#getBizLineName#getOptionNameById 失败：{}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取服务分类名称
     *
     * @return
     */
    private String getServCategName(Integer servCategId) {
        try {
            log.info("#CallSyncDetectionServiceImpl#getBizLineName#getByServCategId 入参：{}", servCategId);
            ResponseDTO<CategServDRO> categServDROResponseDTO = categServListRemoteService.getByServCategId(servCategId);
            log.info("#CallSyncDetectionServiceImpl#getBizLineName#getByServCategId 出参：{}", servCategId);
            return categServDROResponseDTO.getData().getServCategName();
        } catch (Exception e) {
            log.info("#CallSyncDetectionServiceImpl#getBizLineName#getByServCategId 失败：{}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取配置
     */
    private boolean isAllowCity(Integer cityId) {
        List<TagsDRO> tagsDROS = baseCodeService.listBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN, 1069, null, null);
        if (CollectionUtil.isNullOrEmpty(tagsDROS)) {
            return false;
        }
        return tagsDROS.stream().filter(e ->
                Objects.equals(cityId, e.getTwoTypeId()) || NumberUtil.isNullOrZero(e.getTwoTypeId())
        ).findAny().isPresent();
    }
}
